#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    label = new PaintArea(this, pStatus);
    label->setAlignment(Qt::AlignCenter);
    ui->scrollArea->setWidget(label);
    setWindowTitle("Marker");
}

MainWindow::~MainWindow()
{
    delete ui;
    if(label)
        delete label;
}

void MainWindow::closeEvent(QCloseEvent *event)
{
    if(label->getIsSaved() == false)
    {
        if(QMessageBox::information(this, tr("Exit"), tr("Not save, you sure?"), QMessageBox::Yes, QMessageBox::No) == QMessageBox::No)
//        if(QMessageBox::information(this,tr("退出"), tr("当前文件未保存，确定要退出吗？"), QMessageBox::Yes, QMessageBox::No) == QMessageBox::No)
        {
            event->ignore();
            return;
        }
    }
    else
        QMainWindow::closeEvent(event);
}

void MainWindow::on_openAction_triggered()
{
    QString path = QFileDialog::getOpenFileName(this, tr("Open File"), ".", tr("Image Files(*.jpg *.png)"));

    string p = QString2string(path);
    if(path.isEmpty())
        return;
    else
    {
        // 防止内存泄漏
        if (pStatus != nullptr)
            delete pStatus;
        pStatus = new Status;
        string dir(p.begin(), p.begin() + p.find_last_of("/"));
        int index = getFileIndex(dir, p);
        pStatus->setNowImageIndex(index);
        pStatus->createStatus(dir);
        label->setPStatus(pStatus);
        string title = "Marker: " + pStatus->getNowAnnImage().getImageFileName();
        this->setWindowTitle(string2QString(title));
        // 加载某些格式有问题的图片时会出错，但是不影响使用
        if(!(img.load(path)))
        {
            QMessageBox::information(this, tr("Open File Failed"), tr("Open File Failed!"));
            return;
        }
        AnnotationImage ann = pStatus->getNowAnnImage();
        ann.setImageData(QImage2cvMat(img));
        this->setCursor(Qt::ArrowCursor);
        // 设置下拉框
        setComboBox();
        label->setIsSaved(true);
        if(ui->comboBox->count() == 0)
            label->setCanDraw(false);
        else
            label->setCanDraw(true);
        QSize imgSize = img.size();
        QSize labelSize = label->size();
        if(imgSize.width() < labelSize.width() || imgSize.height() < labelSize.height())
            label->setScale(1.0);
        else
        {
            int scaleX = imgSize.width() / labelSize.width();
            int scaleY = imgSize.height() / labelSize.height();
            int scale = scaleX < scaleY ? scaleY : scaleX;
            label->setScale(1.0 / scale);
        }
    }
}

void MainWindow::on_saveAction_triggered()
{
    if(pStatus == nullptr)
        return;
    if(!(pStatus->getNowImageAnn().write()))
        QMessageBox::warning(this, tr("Save Failed"), tr("Save Failed!!"), QMessageBox::Ok);
    else
    {
        QMessageBox::information(this, tr("Save"), tr("Saved successfully!!"), QMessageBox::Ok);
        label->setIsSaved(true);
    }
}

void MainWindow::on_exitAction_triggered()
{
    if(label->getIsSaved() == false)
    {
        if(QMessageBox::information(this, tr("Exit"), tr("Not save, you sure?"), QMessageBox::Yes, QMessageBox::No) == QMessageBox::No)
//        if(QMessageBox::information(this,tr("退出"), tr("当前文件未保存，确定要退出吗？"), QMessageBox::Yes, QMessageBox::No) == QMessageBox::No)
            return;
    }
    else
        exit(0);
}

void MainWindow::on_pointAction_triggered()
{
    if(pStatus == nullptr)
        return;
    // 如果没有新增标注项则不能开始标记
    if(label->getCanDraw() == false)
        return;
    pStatus->setNowSelection(Point_Type);
    this->setCursor(Qt::CrossCursor);
}

void MainWindow::on_rectAction_triggered()
{
    if(pStatus == nullptr)
        return;
    // 如果没有新增标注项则不能开始标记
    if(label->getCanDraw() == false)
        return;
    pStatus->setNowSelection(Rectangle_Type);
    this->setCursor(Qt::CrossCursor);
}

void MainWindow::on_polyAction_triggered()
{
    if(pStatus == nullptr)
        return;
    // 如果没有新增标注项则不能开始标记
    if(label->getCanDraw() == false)
        return;
    pStatus->setNowSelection(Polygon_Type);
    this->setCursor(Qt::CrossCursor);
}

void MainWindow::on_zoomInAction_triggered()
{
    if (pStatus == nullptr)
        return;
    double scale = label->getScale();
    double newscale = scale + SCALE;
    newscale = newscale < 5 ? newscale : scale;
    label->setScale(newscale);
}

void MainWindow::on_zoomOutAction_triggered()
{
    if (pStatus == nullptr)
        return;
    double scale = label->getScale();
    double newscale = scale - SCALE;
    newscale = newscale > 0.1 ? newscale : scale;
    label->setScale(newscale);
}

void MainWindow::on_nextAction_triggered()
{
    if(pStatus == nullptr)
        return;
    // 下一张时自动保存
//    // 将当前标注条目添加到所有标注条目中去
//    pStatus->getNowImageAnn().Add(pStatus->getNowAnnEntry());
    if(!(pStatus->getNowImageAnn().write()))
        QMessageBox::warning(this, tr("Save Failed"), tr("Save Failed!!"), QMessageBox::Ok);
    else
        label->setIsSaved(true);
    // 确保索引不超出边界
    int index = (pStatus->getNowImageIndex()+1) % pStatus->getImageCounts();
    commonFunction(index);
}

void MainWindow::on_previousAction_triggered()
{
    if(pStatus == nullptr)
        return;
    // 上一张时自动保存
//    // 将当前标注条目添加到所有标注条目中去
//    pStatus->getNowImageAnn().Add(pStatus->getNowAnnEntry());
    if(!(pStatus->getNowImageAnn().write()))
        QMessageBox::warning(this, tr("Save Failed"), tr("Save Failed!!"), QMessageBox::Ok);
    else
        label->setIsSaved(true);
    // 确保索引不超出边界
    int index = pStatus->getNowImageIndex()-1;
    index = index < 0 ? 0 : index;
    commonFunction(index);
}

void MainWindow::on_clearAction_triggered()
{
    if(pStatus == nullptr)
        return;
    // 只清空当前标注条目里面的标注项
    ImageAnnEntry &item = pStatus->getNowImageAnn().getImageEntries()[pStatus->getIndex()];
    item.clear();
    item.setItemCounts(0);
    label->setIsSaved(false);
}

int MainWindow::getFileIndex(const string &directoryPath, const string &file)
{
//    QString path = QString::fromStdString(directoryPath);
    QString path = string2QString(directoryPath);

    QStringList filters;
    filters << "*.jpg" << "*.png";
    QDir dir(path);
    if(!dir.exists())
    {
        return -1;
    }
    dir.setNameFilters(filters);
    QFileInfoList list = dir.entryInfoList();

    int file_count = list.count();

    for(int i = 0; i < file_count; ++i)
    {
        string name = QString2string(list.at(i).fileName());
//        string name = list.at(i).fileName().toStdString();
        if((directoryPath + "/" + name) ==  file)
            return i;
    }
    return -1;
}

void MainWindow::on_action_N_triggered()
{
    if(pStatus == nullptr)
        return;
//    // 将当前标注条目添加到所有标注条目中去
//    if(pStatus->getNowAnnEntry().getEntryName() != "")
//        pStatus->getNowImageAnn().Add(pStatus->getNowAnnEntry());

    bool ok;
    // 获取字符串
    QString str = QInputDialog::getText(this, tr("Input"), tr("Name"), QLineEdit::Normal, tr("untitled"), &ok);
//    QString string = QInputDialog::getText(this, tr("请输入"), tr("请输入标注项名称"), QLineEdit::Normal, tr("untitled"), &ok);
    if(ok)
    {
        // 设置当前标注条目
        ImageAnnEntry tmp;
        tmp.setColor(Scalar(0, 255, 0));
        tmp.setEntryName(str.toStdString());
//        pStatus->setNowAnnEntry(tmp);
        // 保存当前条目
        pStatus->getNowImageAnn().Add(tmp);
        pStatus->setImageCounts(pStatus->getImageCounts()+1);
//        pStatus->setHasSavedEntry(true);
        label->setCanDraw(true);
        ui->comboBox->addItem(str);
        int index = ui->comboBox->count()-1;
        ui->comboBox->setCurrentIndex(index);
        pStatus->setIndex(index);
    }
}

void MainWindow::on_action_2_triggered()
{
    QMessageBox::information(this, tr("关于"), tr("xxxxxxxx"), QMessageBox::Ok);
}

void MainWindow::on_comboBox_currentIndexChanged(int index)
{
    if(index < 0)
        return;
    pStatus->setIndex(index);
//    if(index == pStatus->getNowImageAnn().getImageEntries().size())
//    {
//        cout << pStatus->getNowAnnEntry().getEntryName() << endl;
//        // 将当前标注条目添加到所有标注条目中去
//        if(pStatus->getNowAnnEntry().getEntryName() != "")
//            pStatus->getNowImageAnn().Add(pStatus->getNowAnnEntry());
//    }
//    else
//    {
//        cout << pStatus->getNowImageAnn().getImageEntries()[index].getEntryName() << endl;
//        pStatus->setNowAnnEntry(pStatus->getNowImageAnn().getImageEntries()[index]);
//    }
}

void MainWindow::on_chooseColorAction_triggered()
{
    QColor color = QColorDialog::getColor(Qt::red, this, tr("颜色选择"));
    pStatus->getNowImageAnn().getImageEntries()[pStatus->getIndex()].setColor(Scalar(color.blue(), color.green(), color.red()));
}

void MainWindow::commonFunction(int index)
{
    pStatus->setNowImageIndex(index);
    // 更新状态
    pStatus->updateStatus();
    this->setCursor(Qt::ArrowCursor);
    label->setIsSaved(true);

    int count = ui->comboBox->count();

    // 如果下拉框中数量不为0但是没有标注文件
    if(pStatus->getNowImageAnn().getImageEntries().size() == 0 && count != 0)
    {    // 在当前图片标注中新增已经新建过的标注项，但是标注内容设为空
        for(int i = 0; i < ui->comboBox->count(); ++i)
        {
            ImageAnnEntry tmp;
            tmp.setColor(Scalar(0, 255, 0));
            tmp.setEntryName(ui->comboBox->itemText(i).toStdString());
            pStatus->getNowImageAnn().Add(tmp);
            pStatus->setImageCounts(pStatus->getImageCounts()+1);
        }
        // 下拉框显示第一项
        ui->comboBox->setCurrentIndex(0);
    }
    else
        setComboBox();
    // 如果下拉框中没有数据，则不能开始标记
    if(ui->comboBox->count() == 0)
        label->setCanDraw(false);
    else
        label->setCanDraw(true);

    string title = "Marker: " + pStatus->getNowAnnImage().getImageFileName();
    this->setWindowTitle(string2QString(title));
    // 重新显示图像
    update();
}

void MainWindow::setComboBox()
{
    while(ui->comboBox->count() != 0)
        ui->comboBox->removeItem(0);
    for(int i = 0; i < pStatus->getNowImageAnn().getAnnEntryCounts(); ++i)
    {
        string text = pStatus->getNowImageAnn().getImageEntries()[i].getEntryName();
        ui->comboBox->addItem(QString::fromStdString(text));
    }
    if(ui->comboBox->count() != 0)
        ui->comboBox->setCurrentIndex(0);
}
